﻿using Shop.Collect;
using Shop.Model.Activity;
using Shop.Model.ActivityGoods;
using Shop.Model.DB;
using Shop.Model.Goods;
using Shop.Model.GoodsSku;
using Shop.RemoteModel;
using Shop.RemoteModel.ActivityGoods.Model;
using Shop.Service.Interface;
using WeDonekRpc.Client;
using WeDonekRpc.Helper;

namespace Shop.Service.lmpl
{
    internal class ActivityGoodsService : IActivityGoodsService
    {
        private readonly IActivityGoodsCollect _Service;
        private readonly IActivityCollect _Activity;
        private readonly IGoodsSkuCollect _Sku;
        private readonly IGoodsCollect _Goods;
        private readonly IGoodsSkuStateCollect _SkuState;
        public ActivityGoodsService ( IActivityGoodsCollect service,
            IActivityCollect activity,
            IGoodsCollect goods,
            IGoodsSkuStateCollect skuState,
            IGoodsSkuCollect sku )
        {
            this._SkuState = skuState;
            this._Goods = goods;
            this._Service = service;
            this._Activity = activity;
            this._Sku = sku;
        }
        public void Delete ( long id )
        {
            DBShopActivityGoods goods = this._Service.Get(id);
            this._Activity.CheckStatus(goods.ActivityId, ActivityStatus.起草);
            this._Service.Delete(goods);
        }
        public void Delete ( long activityId, long[] ids )
        {
            this._Activity.CheckStatus(activityId, ActivityStatus.起草);
            this._Service.Delete(ids);
        }
        public void SetPrice ( long activityId, Dictionary<long, decimal> price )
        {
            this._Activity.CheckStatus(activityId, ActivityStatus.起草);
            this._Service.SetPrice(price);
        }
        public bool SetPrice ( long id, decimal price, bool isMust )
        {
            DBShopActivityGoods goods = this._Service.Get(id);
            this._Activity.CheckStatus(goods.ActivityId, ActivityStatus.起草);
            return this._Service.SetPrice(goods, price, isMust);
        }
        public ActivityGoodsDto[] Sync ( long activityId, ActivityGoods[] goods )
        {
            this._Activity.CheckStatus(activityId, ActivityStatus.起草);
            DBShopActivityGoods[] datas = this._Service.Sync(activityId, goods);
            if ( datas.IsNull() )
            {
                return Array.Empty<ActivityGoodsDto>();
            }
            ActivityBaseDto activity = this._Activity.Get<ActivityBaseDto>(activityId);
            return this._Format(datas, activity);
        }
        public ActivityGoodsDto[] Gets ( long activityId )
        {
            DBShopActivityGoods[] datas = this._Service.GetsByActivityId<DBShopActivityGoods>(activityId);
            if ( datas.IsNull() )
            {
                return Array.Empty<ActivityGoodsDto>();
            }
            ActivityBaseDto activity = this._Activity.Get<ActivityBaseDto>(activityId);
            return this._Format(datas, activity);
        }
        private ActivityGoodsDto[] _Format ( DBShopActivityGoods[] goods, ActivityBaseDto activity )
        {
            ActivityGoodsDto[] dtos = goods.ConvertMap<DBShopActivityGoods, ActivityGoodsDto>();
            long[] skuId = dtos.Distinct(c => c.SkuId);
            GoodsSkuBase[] skus = this._Sku.Gets<GoodsSkuBase>(skuId);
            long[] noEnable = this._SkuState.GetNoEnable(skuId);
            Dictionary<long, GoodsState> goodsState = this._Goods.GetState(dtos.Distinct(c => c.GoodsId));
            GoodsPitchInActivity[] list = this._Service.GetPitchInActivity(activity.BeginTime, activity.EndTime, skuId);
            dtos.ForEach(c =>
            {
                GoodsSkuBase sku = skus.Find(a => a.SkuId == c.SkuId);
                c.SkuImg = sku.SkuImg;
                c.SkuName = sku.SkuName;
                c.SpecsShow = sku.SpecsShow;
                c.GoodsSku = sku.GoodsSku;
                c.OriginalPrice = sku.Price;
                c.SkuIsEnable = !noEnable.Contains(c.SkuId);
                if ( goodsState.TryGetValue(sku.GoodsId, out GoodsState state) )
                {
                    c.GoodsName = state.GoodsName;
                    c.GoodsStatus = state.Status;
                }
                c.Items = list.ConvertMap<GoodsPitchInActivity, PitchInActivity>(a => a.SkuId == c.SkuId);
            });
            return dtos;
        }
    }
}
